package pl.grabar.clinic.client.web.actions.admin.users;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import pl.grabar.clinic.core.domain.enums.PermissionName;
import pl.grabar.clinic.core.domain.enums.UserType;
import pl.grabar.clinic.core.domain.person.Admin;
import pl.grabar.clinic.core.domain.person.Doctor;
import pl.grabar.clinic.core.domain.person.Receptionist;
import pl.grabar.clinic.core.domain.person.User;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

@Action("new")
@InterceptorRef("grabarStack")
@Results({ @Result(name = "ADMIN", location = "editAdmin.jsp"), @Result(name = "DOCTOR", location = "editDoctor.jsp"),
		@Result(name = "RECEPTIONIST", location = "editReceptionist.jsp"), @Result(name = "USER", location = "editUser.jsp"),
		@Result(name = "input", type = "redirectAction", location = "list") })
public class NewUserAction extends ActionSupport implements Preparable {

	private static final long serialVersionUID = -7229980560574458411L;

	private static final Log LOG = LogFactory.getLog(NewUserAction.class);

	private String userType;

	private User user;

	private Receptionist receptionist;

	private Admin admin;

	private Doctor doctor;
	
	private Map<UserType,String> userTypes = new HashMap<>();
	
	private Map<PermissionName, String> possiblePermissions = new HashMap<>();
	
	@Override
	public void prepare() throws Exception {
		prepareUserData();
	}

	@Override
	public void validate() {
		if (!hasErrors()) {
			if (StringUtils.isBlank(userType)) {
				addActionError(getText("pl.grabar.clinic.client.web.admin.users.actions.no-such-user-type"));
				LOG.error("Blad walidacji w trakcie tworzenia nowego użytkownika. Taki typ użytkownika nie istnieje: " + userType);
			}
		}
	}

	@Override
	public String execute() throws Exception {
		if (UserType.ADMIN.toString().equals(userType)) {
			admin = new Admin();
			admin.setUserType(UserType.ADMIN);
			return userType;
		} else if (UserType.DOCTOR.toString().equals(userType)) {
			doctor = new Doctor();
			doctor.setUserType(UserType.DOCTOR);
			return userType;
		} else if (UserType.USER.toString().equals(userType)) {
			user = new User();
			user.setUserType(UserType.USER);
			return userType;
		} else if (UserType.RECEPTIONIST.toString().equals(userType)) {
			receptionist = new Receptionist();
			receptionist.setUserType(UserType.RECEPTIONIST);
			return userType;
		} else {
			addActionError(getText("pl.grabar.clinic.client.web.admin.users.actions.no-such-user-type"));
			LOG.error("Blad walidacji w trakcie tworzenia nowego użytkownika. Taki typ użytkownika nie istnieje: " + userType);
			return INPUT;
		}
	}
	
	private void prepareUserData(){
		userTypes.put(UserType.ADMIN, getText("pl.grabar.clinic.client.web.labels.admin"));
		userTypes.put(UserType.DOCTOR, getText("pl.grabar.clinic.client.web.labels.doctor"));
		userTypes.put(UserType.USER, getText("pl.grabar.clinic.client.web.labels.user"));
		userTypes.put(UserType.RECEPTIONIST, getText("pl.grabar.clinic.client.web.labels.receptionist"));
		
		possiblePermissions.put(PermissionName.ADMIN, getText(PermissionName.ADMIN.getI18nValue()));
		possiblePermissions.put(PermissionName.DOCTOR, getText(PermissionName.DOCTOR.getI18nValue()));
		possiblePermissions.put(PermissionName.GUEST, getText(PermissionName.GUEST.getI18nValue()));
		possiblePermissions.put(PermissionName.PATIENT, getText(PermissionName.PATIENT.getI18nValue()));
		possiblePermissions.put(PermissionName.RECEPTIONIST, getText(PermissionName.RECEPTIONIST.getI18nValue()));
	}

	/* AKCESORY */

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Admin getAdmin() {
		return admin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}

	public Doctor getDoctor() {
		return doctor;
	}

	public void setDoctor(Doctor doctor) {
		this.doctor = doctor;
	}

	public String getUserType() {
		return userType;
	}

	public void setUserType(String userType) {
		this.userType = userType;
	}

	public Map<UserType, String> getUserTypes() {
		return userTypes;
	}

	public void setUserTypes(Map<UserType, String> userTypes) {
		this.userTypes = userTypes;
	}

	public Map<PermissionName, String> getPossiblePermissions() {
		return possiblePermissions;
	}

	public void setPossiblePermissions(Map<PermissionName, String> possiblePermissions) {
		this.possiblePermissions = possiblePermissions;
	}

	public Receptionist getReceptionist() {
		return receptionist;
	}

	public void setReceptionist(Receptionist receptionist) {
		this.receptionist = receptionist;
	}

}
